Object.defineProperty(Object, "assign", {
  value: function (target, sources) {
    if (target == null) {
      throw TypeError("Cannot convert undefined or null to Object");
    }

    target = new Object(target);
    var args = [].slice.call(arguments, 1);

    for (var index = 0; index < args.length; index++) {
      var source = args[index];
      if (source == null) continue;
      for (var key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          target[key] = source[key];
        }
      }
    }

    return target;
  },
  writable: true,
  configurable: true,
});
if (!Array.from) {
  Array.from = (function () {
    var toStr = Object.prototype.toString;
    var isCallable = function (fn) {
      return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
    };
    var toInteger = function (value) {
      var number = Number(value);
      if (isNaN(number)) { return 0; }
      if (number === 0 || !isFinite(number)) { return number; }
      return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
    };
    var maxSafeInteger = Math.pow(2, 53) - 1;
    var toLength = function (value) {
      var len = toInteger(value);
      return Math.min(Math.max(len, 0), maxSafeInteger);
    };

    // The length property of the from method is 1.
    return function from(arrayLike/*, mapFn, thisArg */) {
      // 1. Let C be the this value.
      var C = this;

      // 2. Let items be ToObject(arrayLike).
      var items = Object(arrayLike);

      // 3. ReturnIfAbrupt(items).
      if (arrayLike == null) {
        throw new TypeError("Array.from requires an array-like object - not null or undefined");
      }

      // 4. If mapfn is undefined, then let mapping be false.
      var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
      var T;
      if (typeof mapFn !== 'undefined') {
        // 5. else
        // 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
        if (!isCallable(mapFn)) {
          throw new TypeError('Array.from: when provided, the second argument must be a function');
        }

        // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
        if (arguments.length > 2) {
          T = arguments[2];
        }
      }

      // 10. Let lenValue be Get(items, "length").
      // 11. Let len be ToLength(lenValue).
      var len = toLength(items.length);

      // 13. If IsConstructor(C) is true, then
      // 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
      // 14. a. Else, Let A be ArrayCreate(len).
      var A = isCallable(C) ? Object(new C(len)) : new Array(len);

      // 16. Let k be 0.
      var k = 0;
      // 17. Repeat, while k < len… (also steps a - h)
      var kValue;
      while (k < len) {
        kValue = items[k];
        if (mapFn) {
          A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
        } else {
          A[k] = kValue;
        }
        k += 1;
      }
      // 18. Let putStatus be Put(A, "length", len, true).
      A.length = len;
      // 20. Return A.
      return A;
    };
  }());
}

class LouAria {
  constructor(element) {
    this.element = element;
    if (!(this.element instanceof Element)) {
      throw Error("必须传入一个Element对象");
    }
    if (this.element.dataset.louAria) {
      throw new Error("一个元素只能被创建一次LouAria实例");
    }
    if (this.element.getAttribute("data-clear-aria-region") === "true") {
      throw new Error('"data-clear-aria-region"属性为true的元素无法实例化，请在实例化时进行该属性的判断。');
    } else {
      this.element.louAria = this;
      this.element.dataset.louAria = true;
    }

    recordInstances.apply(this); // 记录实例

    function recordInstances() {
      var constructor = this.constructor;
      if (!constructor.hasOwnProperty("instances")) constructor.instances = [];
      constructor.instances.push(this);
    }
  }

  static version = "2.02_2"

  static initMethods = {
    // 初始化运行的函数

    initOldMobile: function () {
      // 判断老年版和普通版
      var storage = window.localStorage;
      // 判断localstorage存储中是否含有key为mode，true则是老年版，添加老年版class类名old_type
      if (storage.hasOwnProperty("mode")) {
        $("body,html").addClass("old_type");
      } else {
        $("body,html").removeClass("old_type");
      }
      // 进入老年版按钮点击，创建存储键值，并在body添加class类名
      $(".new_boount").click(function () {
        // 进入老年版按钮点击
        $("body,html").addClass("old_type");
        storage.setItem("mode", 2);
      });
      // 退出老年版按钮点击，删除存储键值，并移除body的class类名
      $(".old_boount").click(function () {
        $("body,html").removeClass("old_type");
        storage.removeItem("mode");
      });
      // 手机版，是否是移动端设备以及根据浏览器页面宽度（国产浏览器）来判断
      if (LouAria.isMobile()) {
        $("body,html").removeClass("old_type").addClass("mobile_type");
        storage.removeItem("mode"); // 页面的head头部的meta是否有name为viemport标签，如无则添加
        if (!$("meta[name=viewport]").attr("content")) {
          $("head").prepend('<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">');
        }
      } else {
        $("body,html").removeClass("mobile_type");
      }
    },

    initStyle: function (options) {
      // 初始化style

      var options = options || {};
      var themeColor = options.themeColor || "#007cda";
      var styleStr = ".loginBtns{position:relative;display:flex}.loginBtns:hover>div{display:block}.loginBtns .loginItems,.loginBtns .user-center{display:none;padding:0.625em 0 0.375em;top:100%;position:absolute;left:50%;transform:translateX(-50%);line-height:2;background-image:url();background-size:100% 100%}.loginBtns .loginItems a,.loginBtns .user-center a{padding:0 1em;display:block;white-space:nowrap;color:black}html{min-width:1200px;font-size:16px}html.old_type{font-size:32px}html.mobile_type{min-width:auto;font-size:4vw}.UseInMobile .UseInMobileHidden,body[aria-status=\"true\"].UseInMobile .UseInMobileHidden{display:none !important}.ariabodytopfiexed .aria-hidden{display:none !important}.mobile_type .mobile-hidden{display:none !important}:root{--theme-color: ".concat(themeColor, "}body.mobile_type.UseInMobile.ariaMobileHeaderIntop{padding-bottom:85px}a{transition:all 0.2s}a *{transition:all 0.2s}a:hover{transition:all 0.2s}a:hover *{transition:all 0.2s}[role=\"button\"]{cursor:pointer}.a-hover a:hover{color:").concat(themeColor, " !important;color:var(--theme-color) !important}.old_boount{display:none}.old_type *{box-sizing:border-box;cursor:url(//zjjcmspublic.oss-cn-hangzhou-zwynet-d01-a.internet.cloud.zj.gov.cn/jcms_files/jcms1/web3096/site/images/1/cur/mouse_default.cur) 8 0,auto !important}.old_type a,.old_type a *,.old_type button,.old_type button *,.old_type [role=\"button\"],.old_type [role=\"button\"] *,.old_type [role=\"link\"],.old_type [role=\"link\"] *{cursor:url(//zjjcmspublic.oss-cn-hangzhou-zwynet-d01-a.internet.cloud.zj.gov.cn/jcms_files/jcms1/web3096/site/images/1/cur/pointer.cur) 15 0,auto !important}.old_type .new_boount{display:none}.old_type .old_boount{display:block}.ariafocus:focus,.ariafocus{outline:2px solid #fcff00 !important;transition:outline 250ms !important;z-index:9999}.ariaregion,[aria-regionactive=\"true\"]:focus{outline:2px solid #ff6c00 !important;transition:outline 250ms !important}.region-show{display:block !important}.region-hide{display:none !important}.ariafooter{width:100% !important}body .ariaiconcloseDiv{padding:3px !important;display:flex;justify-content:center;align-items:center}body .ariaiconcloseDiv i::before{position:relative;top:auto;left:auto}");
      $("head").prepend($("<style id='lou-aria-init-style'>" + styleStr + "</style>"));
    },

    recoverTabindex: function () {
      // 无障碍打开后恢复tabindex

      if (!LouAria.isMobile()) {
        $("[tabindex]").each(function () {
          $(this).attr("data-memory-tabindex", $(this).attr("tabindex"));
        });
        observeTabindex();
        $("p:not([setedaria='true'])").attr("tabindex", "0");
        LouAria.observeAriaStatus(function () {
          $("[data-memory-tabindex]").each(function () {
            if ($(this).attr("data-memory-tabindex") !== "false") $(this).attr("tabindex", $(this).attr("data-memory-tabindex"));
          });
        });

        function observeTabindex() {
          // 监听[tabindex],p的tabindex属性的变化，每次变化将其值存入data-memory-tabindex属性中

          LouAria.addObserver(
            function (mutation) {
              var attributeName = mutation.attributeName;
              var target = mutation.target;
              var tabindex = $(target).attr("tabindex");

              if (
                attributeName === "tabindex" &&
                tabindex !== undefined &&
                $(target).attr("data-memory-tabindex") !== "false"
              ) {
                $(target).attr("data-memory-tabindex", tabindex);
              }
            },
            $("[tabindex],p"),
            { attributes: true, attributeOldValue: true }
          );
        }
      }
    },

    dataClearAriaRegion: function () {
      // [data-clear-aria-region]的元素清除智能盲道

      $("[data-clear-aria-region='true']").removeAttr("aria-region aria-regiontype tabindex aria-label aria-autolabel");
      LouAria.addObserver(function (mutation) {
        var attributeName = mutation.attributeName;
        var target = mutation.target;
        var dataClearAriaRegion = $(target).attr("data-clear-aria-region");

        if (attributeName === "aria-region" && dataClearAriaRegion !== undefined && $(target).attr("aria-region") !== undefined) {
          $(target).attr("data-memory-tabindex", "false");
          $(target).removeAttr("aria-region aria-regiontype tabindex aria-label aria-autolabel");
        }
      }, $("[data-clear-aria-region='true']"), { attributes: true, attributeOldValue: true, });
    },

    jcA11y: function () {
      // 底部找错按钮添加tabindex
      $("#_span_jiucuo >img").attr({
        "tabindex": "0",
        "role": "link",
        "aria-label": "打开新窗口链接,政府网站找错",
      });
      // 底部找错按钮添加回车事件
      $("#_span_jiucuo >img").keydown(function (e) {
        if (e.keyCode === 13) {
          this.click();
        }
      });
    },

    aA11y: function (target = "iframe,html") {
      // a标签无障碍
      var selector = "a:not([role]),[role='link']";

      $(target).each(function () {
        try {
          if (navigator.userAgent.match(/mobile/i) || $("html").outerWidth() > 1024) {
            // 手机端，去除title属性

            $(this).contents().find(selector).each(function () {
              $(this).attr("title", "");
            });
          }
        } catch (error) {
          return true;
        }
      });
    },

    pgToolBarA11y: function () {
      // 分页器添加无障碍属性

      var isMobile = LouAria.isMobile();
      $(".default_pgToolbar").attr({
        "aria-label": isMobile ? "提示：您已进入分页交互区" : "提示：您已进入分页交互区，按下tab键浏览信息",
        "aria-region": "true",
        "aria-regiontype": "3",
      });
      $(".default_pgFirst").attr("aria-label", "第一页");
      $(".default_pgPrev").attr("aria-label", "上一页");
      $(".default_pgNext").attr("aria-label", "下一页");
      $(".default_pgSearchInfo").html("<p>" + $(".default_pgSearchInfo").html() + "</p>");
    },

    swiperDuplicateA11y: function () {
      // Swiper.js的轮播图复制的元素无障碍处理

      $(".swiper-slide-duplicate").attr("aria-hidden", "true");
      $(".swiper-slide-duplicate *").attr({
        setedaria: "true",
        tabindex: "-1",
      });
    },

    closeAriaClearRegionFocus() {
      LouAria.observeAriaStatus(null, function () {
        $(".ariafocus,.ariaregion,[aria-regionactive='true']:focus").removeClass("ariafocus ariaregion");
      });
    },
  }

  static init(options) {
    // $("html").attr("aria-region", "false");
    // window.ariaRegion = new AriaRegion($("html")[0]);

    var options = options || this.initMethods;
    var initMethods = this.initMethods;

    $(function () {
      options = Object.assign({}, initMethods, options);

      for (var key in options) {
        if (options[key] && initMethods[key] instanceof Function && !window[key]) {
          initMethods[key](options[key] instanceof Function ? undefined : options[key]);
        }
      }
      $("p[tabindex='-1']").attr("tabindex", "");
    });
  }
  static addAriaAttr(option) {
    var option = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    var ariaRegion = $(option.target).attr("aria-region") === "false" ? false : true;
    var isMobile = LouAria.isMobile();
    var region; // 区域
    var target = option.target; // 目标元素选择器
    var regionType = Number(option.regionType) || 1; // 区域id
    var regionDescribe = option.regionDescribe || ""; // 区域描述
    var navColTarget = option.navColTarget; // 栏目元素
    var navColDescribe = "";  // 栏目描述
    var navColArr = []; // 栏目字符串数组
    var attrObj = {
      "aria-regiontype": regionType,
      "aria-region": "true",
      "aria-autolabel": "true",
    };

    if (ariaRegion) {
      switch (regionType) {
        case 1:
          region = "视窗区";
          break;
        case 2:
          region = "导航区";
          break;
        case 3:
          region = "交互区";
          break;
        case 4:
          region = "服务区";
          break;
        case 5:
          region = "列表区";
          break;
        case 6:
          region = "正文区";
          break;
        default:
          break;
      }

      // 在文字描述中添加栏目信息
      if (navColTarget) {
        navColDescribe = "，有";
        $(navColTarget).each(function () {
          navColArr.push($(this).text().trim().replace(/[\n\r]/g, ""));
        });
        navColArr.forEach(function (navCol, index) {
          if (index <= 1) {
            navColDescribe += navCol + "、";
          } else if (index === 2) {
            navColDescribe += navCol + "等栏目";
          }
        });
      }
      attrObj["aria-label"] = region + "，提示：您已进入" + regionDescribe + region + navColDescribe + (isMobile ? "" : "，按下tab键浏览信息");
      $(target).attr(attrObj);
    } else {
      $(target).removeAttr("aria-label aria-regiontype");
    }
  }
  static dispatchEvent(target, eventString) {
    // 触发事件
    var event;
    if (this.isIe()) {
      event = document.createEvent('CustomEvent');
      event.initCustomEvent(eventString, true, false, null);
    } else {
      event = new CustomEvent(eventString, { bubbles: true });
    }
    target.dispatchEvent(event);
  }
  static isMobile() {
    // 是否是移动端

    return !!(navigator.userAgent.match(/mobile/i) && screen.width <= 1024)
  }
  static isIe() {
    return window.ActiveXObject || "ActiveXObject" in window;
  }
  static loadScript(url) {
    // 动态加载脚本
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = url;
    document.body.appendChild(script);
  }
  static iframeEventPenetrate(iframe) {
    // iframe事件穿透
    // 当iframe内的元素点击或键盘按下时，会触发iframe的iframeClickOrKeydown自定义事件，iframe元素的事件对象存储在自定义事件对象e的detail属性内

    ['click', 'keydown'].forEach(function (item) {
      $(iframe).contents()[item](function (e) {
        var event = new CustomEvent("iframeClickOrKeydown", {
          bubbles: true,
          detail: e,
        });
        $(iframe)[0].dispatchEvent(event);
      });
    });
  }
  static mobileAriaHtmlAddFontSize(wzaBtnTarget, forced) {
    // 手机端无障碍切换字体时html添加fontsize
    /**
     * @function 解决在移动端部分网站下安徽大家无障碍切换字体功能失效问题
     * @param { String | Element | jQuery.fn.init } wzaBtnTarget 为页面无障碍按钮选择器的字符串或元素
     * @param { Boolean } forced 是否强制为每个元素设置字体，通过添加 ".mobile_type.font-scale-... *:not(...) {font-size: 1rem !important;}" 样式规则。
     */

    try {
      let wzaBtnTarget = wzaBtnTarget || (() => { throw Error("缺少必填参数") })();
    } catch (error) {

    }

    var forced = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;

    removeAriaBodyScale();
    var interval = setInterval(function () {
      if (window.aria && aria.status()) {
        handleWzaBtnClick(wzaBtnTarget);

        // 开启无障碍按钮点击
        $(wzaBtnTarget).click(function () {
          handleWzaBtnClick(wzaBtnTarget);
        });

        clearInterval(interval);
      }
    }, 1000);

    function setHtmlFontSize() {
      var isMobile = LouAria.isMobile();
      var fontScale = aria.getMessageData().fontScale;
      var fontScaleSize = fontScale === 1 ? "m" : fontScale === 1.15 ? "l" : fontScale === 1.3 ? "xl" : "";
      var htmlFontScaleStyleStr = 'html.mobile_type.font-scale-m{font-size:4vw}html.mobile_type.font-scale-l{font-size:4.6vw}html.mobile_type.font-scale-xl{font-size:5.2vw}';
      var forcedFontScaleStyleStr = forced ? '.mobile_type.font-scale-m *:not(.am-modal-active *,.ariafooter *),.mobile_type.font-scale-l *:not(.am-modal-active *,.ariafooter *),.mobile_type.font-scale-xl *:not(.am-modal-active *,.ariafooter *){font-size:1rem !important}' : "";

      if (isMobile) {
        $("html").removeClass("font-scale-m font-scale-l font-scale-xl");
        $("html").addClass(fontScaleSize ? "font-scale-" + fontScaleSize : "").addClass("UseInMobile");
        if (!$("#html-font-scale").length) {
          $("body").append("<style id=\"html-font-scale\">".concat(htmlFontScaleStyleStr, forcedFontScaleStyleStr, "</style>"));
        }
        $("body").addClass("UseInMobile");
      }
    }
    function removeHtmlFontSize() {
      $("html").removeClass("font-scale-m font-scale-l font-scale-xl UseInMobile");
      $("#html-font-scale").remove();
    }
    function addAriaEndClickEvent() {
      // 无障碍关闭按钮点击
      setIntervalLimitTimeOut(function () {
        $(".ariafooter li:last-of-type,.ariaBtns ariaLi ariai.ariaexit").click(function () {
          removeHtmlFontSize();
          $(wzaBtnTarget).show();
        });
        // 无障碍设置字体按钮点击
        $(".Set-font li label").click(function () {
          setHtmlFontSize();
          $("#ariabodyscale").remove();
        });
      }, function () {
        return $(".ariafooter li:last-of-type,.ariaBtns ariaLi ariai.ariaexit").length !== 0;
      });
    }
    function handleWzaBtnClick(target) {
      setHtmlFontSize();
      $(target).hide();
      addAriaEndClickEvent();
    }
    function setIntervalLimitTimeOut(callback, limitCallback, intervalDelay, timeoutDelay) {
      var intervalDelay = intervalDelay || 500;
      var timeoutDelay = timeoutDelay || 1000;

      var intervalId = setInterval(function () {
        if (limitCallback()) {
          callback();
          clearInterval(intervalId);
          clearTimeout(timeoutId);
        }

        var timeoutId = setTimeout(function () {
          clearInterval(intervalId);
        }, timeoutDelay);
      }, intervalDelay);
    }
    function removeAriaBodyScale() {
      // 去除id为ariabodyscale的style元素

      $("#ariabodyscale").remove();
      LouAria.addObserver(function (mutationRecord) {
        if ($(mutationRecord.addedNodes).attr("id") === "ariabodyscale") $(mutationRecord.addedNodes).remove();
      }, $("body"), { attributes: false, childList: true });
    }
  }
  static addObserver(callback, target, options) {
    /**
     * 回调函数
     * @callback DoCallback
     * @param { MutationRecord } mutationRecord // 变化的记录
     * @param { MutationObserver } observer // 监听器
     */

    /**
     * @function 给指定元素添加监听
     * @param { DoCallback } callback 执行的操作
     * @param { String | Element | jQuery.fn.init } target 添加监听的目标元素
     * @param { Object } options 监听配置
     * @return { MutationObserver }
     */

    var _callback = function (mutationsList, observer) {
      for (var i in mutationsList) {
        var mutationRecord = mutationsList[i];
        callback(mutationRecord, observer);
      }
    };

    var observer = new MutationObserver(_callback);
    $(target).each(function () {
      observer.observe(this, options);
    });

    return observer;
  }
  static bindAttrsProps(element, obj, attrsPropsMap, callback) {
    /**
     * 回调函数
     * @callback DoCallback
     * @param { String } property 变化的对象属性名
     */

    /**
     * @function 元素属性和对象属性的双向绑定
     * @param { Element } element 指定元素
     * @param { Object } obj 指定的对象
     * @param { Object } attrsPropsMap 元素属性名与对象属性名的映射
     * @param { DoCallback } callback 元素或对象属性改变触发的操作
     */

    bindAttrs(element, obj, attrsPropsMap, callback);
    bindProps(element, obj, attrsPropsMap, callback);

    function bindProps(element, obj, attrsPropsMap, callback) {
      for (let attr in attrsPropsMap) {
        let property = attrsPropsMap[attr];

        $(element).attr(attr, obj[property]);

        // console.log($(element).attr(attr));
        Object.defineProperty(obj, property, {
          get() {
            return $(element).attr(attr);
          },
          set(value) {
            $(element).attr(attr, value);
            if (callback) callback(property);
          },
        });
      }
    }
    function bindAttrs(element, obj, attrsPropsMap, callback) {
      var config = { attributes: true };
      var _callback = (mutationList, observer) => {
        mutationList.forEach((mutation) => {
          switch (mutation.type) {
            case "attributes":
              let attributeName = mutation.attributeName;

              observer.disconnect();
              if (attributeName in attrsPropsMap) {
                let instanceProperty = attrsPropsMap[attributeName];
                if (obj[instanceProperty] !== $(element).attr(attributeName)) obj[instanceProperty] = $(element).attr(attributeName);
                if (callback) callback(instanceProperty);
              }
              observer.observe(element, config);
              break;
          }
        });
      };

      var observer = new MutationObserver(_callback);
      observer.observe(element, config);
    }
  }
  static observeAriaStatus(startCallback, endCallback) {
    // 观察无障碍状态

    var observer = LouAria.addObserver(
      function (mutation) {
        var attributeName = mutation.attributeName;
        var target = mutation.target;

        if (attributeName === "aria-status") {
          if ($(target).attr("aria-status") === "true") {
            if (startCallback) startCallback(); // 打开后运行的函数
          } else {
            if (endCallback) endCallback(); // 关闭后运行的函数
          }
        }
      },
      $("body")[0],
      { attributes: true, attributeOldValue: true }
    );

    return observer;
  }
}

class AriaRegion extends LouAria {
  constructor(element, options) {
    super(element);

    var defaultOptions = {
      ariaRegion: true,
      ariaRegiontype: this.element.getAttribute("aria-regiontype") || 1,
    };
    options = Object.assign(defaultOptions, options);

    for (let key in options) {
      this[key] = options[key];
    }
    this.element.tabIndex = 0;

    $(this.element).keydown(this.onSwitchRegionKeydown.bind(this));

    LouAria.bindAttrsProps(this.element, this, this.constructor.attrsPropsMap, this.addAriaAttr.bind(this));
    this.addAriaAttr();

    // 初始化AriaRegion
    var initAriaRegion = AriaRegion.#initAriaRegion;
    if (initAriaRegion.runned !== true) {
      initAriaRegion();
      initAriaRegion.runned = true;
    }
  }

  static attrsPropsMap = {
    "aria-region": "ariaRegion",
    "aria-regiontype": "ariaRegiontype",
    "data-region-describe": "regionDescribe",
    "data-region-describedby": "regionDescribedby",
    "data-nav-col-target": "navColTarget",
  } // key: 元素的属性名，value: 实例属性名

  static #initAriaRegion() {
    $("html").keydown(function (event) {
      var flag = false;

      if (aria.status() && event.altKey) {
        switch (event.key) {
          case "1":
          case "2":
          case "3":
          case "4":
          case "5":
          case "6":
            setFocusToFirstRegion(event.key);
            flag = true;
            break;

          default:
            break;
        }
      }

      if (flag) {
        event.stopPropagation();
        event.preventDefault();
        event.stopImmediatePropagation();
      }
    });

    function setFocusToFirstRegion(type) {
      var element = $(`[aria-regiontype='${type}']`)[0];

      element?.louAria?.regionFocus();
    }
  }

  addAriaAttr() {
    var ids = this.regionDescribedby?.split(" ");
    var regionDescribe = "";
    ids?.forEach(function (id) {
      var text = $("#" + id).text().trim() || $("#" + id).attr("title")?.trim() || $("#" + id).attr("aria-label")?.trim();
      regionDescribe += text;
    });
    regionDescribe = regionDescribe || this.regionDescribe;

    LouAria.addAriaAttr({
      target: this.element,
      regionType: this.ariaRegiontype,
      regionDescribe: regionDescribe,
      navColTarget: this.navColTarget,
    });
  }

  setFocusToNextRegion(type) {
    let nextRegionNode = getNextRegionNode.call(this, type);

    this.regionBlur();
    if (nextRegionNode) {
      if (!nextRegionNode.louAria) new AriaRegion(nextRegionNode); // 兼容未使用AriaRegion对象的无障碍
      nextRegionNode.louAria.regionFocus();
    }

    function getNextRegionNode(type) {
      var index = $('[aria-region="true"]').index(this.element);
      var afterRegions = Array.from($('[aria-region="true"]')).slice(index + 1);

      return $(afterRegions).filter(`[aria-regiontype="${type}"]`)[0] || $(`[aria-regiontype="${type}"]`)[0];
    }
  }

  regionFocus() {
    var element = this.element;

    // 其余区域失去焦点
    $('[aria-region="true"][class*="ariaregion"]').each(function () {
      this.louAria.regionBlur();
    });

    // 当前区域激活
    $(element).addClass(`currentRegion${this.ariaRegiontype} ariaregion ariafocus`);
    if ($(element).is(":hidden")) element.louAria.regionShow();
    element.focus();
  }

  regionBlur() {
    var element = this.element;

    $(element).removeClass(`currentRegion${this.ariaRegiontype} ariaregion ariafocus region-show`).removeAttr("aria-regionactive").blur();
    $(element).find(".ariafocus").removeClass("ariafocus");
  }

  regionShow() {
    $(this.element).addClass("region-show").removeClass("region-hide");
  }

  regionHide() {
    $(this.element).addClass("region-hide").removeClass("region-show");
  }

  /* 事件处理 */

  onSwitchRegionKeydown(event) {
    var flag = false;

    if (aria.status() && event.altKey) {
      switch (event.key) {
        case "1":
        case "2":
        case "3":
        case "4":
        case "5":
        case "6":
          this.setFocusToNextRegion(event.key);
          flag = true;
          break;

        default:
          break;
      }
    }

    if (flag) {
      event.stopPropagation();
      event.preventDefault();
      event.stopImmediatePropagation();
    }
  }
}

class PopupAriaRegion extends AriaRegion {
  constructor(element, options, ariaControls) {
    super(element);

    var defaultOptions = {
      escHide: element.dataset.escHide || "false",
      regionActivedDispatchEvent: element.dataset.regionActivedDispatchEvent || "true",
      regionDescribe: (ariaControls.element.textContent || "").trim(),
    };
    options = Object.assign(defaultOptions, options);

    for (let key in options) {
      this[key] = options[key];
    }
    this.ariaControls = ariaControls;

    element.addEventListener("keydown", this.onEscPopupKeydown.bind(this));
    element.addEventListener("focusout", this.onFocusout.bind(this));
    element.addEventListener("focusin", this.onFocusin.bind(this));
  }

  static attrsPropsMap = Object.assign({
    "data-esc-hide": "escHide",
    "data-region-actived-dispatch-event": "regionActivedDispatchEvent",
  }, super.attrsPropsMap);

  regionBlur() {
    super.regionBlur();
    if (this.escHide === "false") this.regionShow();
  }

  /* 事件处理 */

  onEscPopupKeydown(event) {
    var flag = false;

    switch (event.key) {
      case "Escape":
        if (this.escHide === "true") this.regionHide();
        this.regionBlur();
        this.ariaControls.element.focus();
        flag = true;
        break;

      default:
        break;
    }

    if (flag) {
      event.stopPropagation();
      event.preventDefault();
      event.stopImmediatePropagation();
    }
  }

  onFocusout(event) {
    if (!this.element.contains(event.relatedTarget) && this.ariaControls.hoverPatch === "true") {
      $(this.element).removeClass("region-show");
    }
  }

  onFocusin(event) {
    if (this.element === event.srcElement && this.regionActivedDispatchEvent === "true") {
      this.ariaControls.dispatchPopupMethodEvent();
    }
  }
}

class AriaControls extends LouAria {
  constructor(element, options, popupAriaRegionOption) {
    super(element);

    // 当popupId属性值有重复，报错
    $("[data-popup-id]").each(function () {
      if ($(`[data-popup-id="${this.dataset.popupId}"]`).length > 1) throw Error("有相同值的data-popup-id元素");
    });

    element.tabIndex = 0;
    element.setAttribute("aria-haspopup", "true");

    var defaultOptions = {
      popupId: element.dataset.popupId,
      popupMethod: element.dataset.popupMethod || "mouseover",
      focusDispatchEvent: element.dataset.focusDispatchEvent || element.dataset.hoverPatch === "true" ? "false" : "true",
      enterDispatchEvent: element.dataset.enterDispatchEvent || "true",
      hoverPatch: element.dataset.hoverPatch || "false",
      tabGroup: element.dataset.tabGroup || null,
    };
    options = Object.assign(defaultOptions, options);

    for (let key in options) {
      this[key] = options[key];
    }

    this.popupAriaRegion = new PopupAriaRegion($("#" + this.popupId)[0], popupAriaRegionOption, this);

    if (this.tabGroup) {
      var sameGroupInstances = this.constructor.instances.filter((ariaControls) => { return ariaControls.tabGroup === this.tabGroup });

      if (sameGroupInstances.length === 1) {
        // 初始化数组
        this.tabGroupNodes = [];
        this.popupGroupNodes = [];
      } else {
        // 指向已有数组的引用
        this.tabGroupNodes = sameGroupInstances[sameGroupInstances.length - 2].tabGroupNodes;
        this.popupGroupNodes = sameGroupInstances[sameGroupInstances.length - 2].popupGroupNodes;
      }

      this.tabGroupNodes.push(element);
      this.popupGroupNodes.push(this.popupAriaRegion.element);

      element.addEventListener(this.popupMethod, this.tabSwitch.bind(this));
    }

    if (this.hoverPatch === "true") {
      $([this.element, this.popupAriaRegion.element]).hover(function () {
        this.popupAriaRegion.regionShow();
      }.bind(this), function () {
        this.popupAriaRegion.regionHide();
      }.bind(this));

      $([this.element, this.popupAriaRegion.element]).click(function () {
        if (LouAria.isMobile) $(this).mouseover();
      });
    }

    LouAria.bindAttrsProps(this.element, this, this.constructor.attrsPropsMap);

    $(element).keydown(this.onKeydown.bind(this));
    $(element).focusin(this.onFocusin.bind(this));
  }

  static attrsPropsMap = {
    "data-popup-method": "popupMethod",
    "data-focus-dispatch-event": "focusDispatchEvent",
    "data-enter-dispatch-event": "enterDispatchEvent",
  };

  onKeydown(event) {
    var flag = false;

    if (event.ctrlKey) {
      switch (event.key) {
        case "ArrowDown":
          if (this.enterDispatchEvent === "true")
            this.dispatchPopupMethodEvent();
          if ($(this.popupAriaRegion.element).is(":hidden"))
            this.popupAriaRegion.regionShow();

          this.popupAriaRegion.element.focus();
          flag = true;
          break;

        default:
          break;
      }
    }

    if (flag) {
      event.stopPropagation();
      event.preventDefault();
      event.stopImmediatePropagation();
    }
  }

  onFocusin(event) {
    if (this.focusDispatchEvent === "true") this.dispatchPopupMethodEvent();
    event.stopPropagation();
    event.preventDefault();
    event.stopImmediatePropagation();
  }

  tabSwitch(event) {
    $(this.popupGroupNodes).each(function () {
      this.louAria.regionHide();
    });
    this.popupAriaRegion.regionShow();
    $(this.tabGroupNodes).removeClass("active");
    $(this.element).addClass("active");
  }

  dispatchPopupMethodEvent() {
    LouAria.dispatchEvent(this.element, this.popupMethod);
  }
}

// LouAria.init({
//   initStyle: {
//     themeColor: "red",
//   },
// });

// AriaRegion.init();

// $('[aria-region="true"]').each(function () {
//   var ariaRegion = new AriaRegion(this);
//   // console.log(ariaRegion);
// });

// $('[data-popup-id]').each(function () {
//   var ariaControls = new AriaControls(this);
//   // console.log(ariaControls);
// });